package com.diqye.db.model;
import static com.diqye.db.exception.XAssert.asertnotnull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.diqye.db.Tinfo;
import com.diqye.db.manage.XManage;

public class XModel extends HashMap<String, Object> {

	private Tinfo tinfo;
	private static final long serialVersionUID = 7526639248811785589L;
	
	/**
	 * 是否小写形式存储Key
	 */
	public boolean lowerCase;
	
	public XModel(Class<? extends Tinfo> clazz){
		this(XManage.getTinfo(clazz));
	}
	public XModel(Tinfo tinfo){
		this.tinfo = tinfo;
	}
	public XModel(){
		this(true);
	}
	/**
	 * 
	 * @param ignorecase 是否忽略大小写
	 */
	public XModel(boolean ignorecase){
		super();
		this.lowerCase = ignorecase;
	}

	
	@Override
	public void putAll(Map<? extends String, ? extends Object> m) {
		for(String key:m.keySet())
			put(key,m.get(key));
	}
	public boolean containsKey(Object key) {
		return super.containsKey(casekey(key));
	}
	
	@Override
	public Object remove(Object key) {
		return super.remove(casekey(key));
	}
	public Object get(Object key) {
		return super.get(casekey(key));
	}
	
	public Object g(String key){
		return get(key);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public XModel getModel(String key){
		Object o = get(key);
		if(o instanceof Map){
			XModel r= new XModel();
			r.putAll((Map)o);
			return r;
		}
		return null;
	}
	public Object put(String key, Object value) {
		return super.put(casekey(key), value);
	}

	public XModel set(String key, Object value){
		put(key,value);
		return this;
	}
	
	public XModel s(String key, Object value){
		return set(key,value);
	}
	public XModel setToInt(String key, Object value){
		int nvalue;
		if(value instanceof Integer){
			nvalue = (Integer)value;
		}else{
			nvalue = Integer.valueOf(String.valueOf(value));
		}
		put(key,nvalue);
		return this;
	}
	
	public XModel sti(String key, Object value){
		return setToInt(key,value);
	}
	
	public XModel setToStr(String key, Object value){
		String nvalue;
		if(value instanceof String){
			nvalue = (String)value;
		}else{
			nvalue = String.valueOf(value);
		}
		put(key,nvalue);
		return this;
	}
	
	public XModel sts(String key, Object value){
		return setToStr(key,value);
	}
	
	public XModel setToDouble(String key, Object value){
		double nvalue;
		if(value instanceof Double){
			nvalue = (Double)value;
		}else{
			nvalue = Double.valueOf(String.valueOf(value));
		}
		put(key,nvalue);
		return this;
	}
	
	public XModel std(String key, Object value){
		return setToDouble(key,value);
	}
	
	public String getToStr(String key){
		Object o = get(key);
		//需要将大文本类型，或者二进制转换为JS类型
		return o == null? null: String.valueOf(o);
	}
	
	public String gts(String key){
		return this.getToStr(key);
	}
	public Number getNumber(String key){
		return (Number)get(key);
	}
	
	
	public Number gn(String key){
		return getNumber(key);
	}
	public Integer getInt(String key){
		Number num = getNumber(key);
		return num == null? null: num.intValue();
	}
	public Integer gi(String key){
		return getInt(key);
	}
	
	public double getDouble(String key){
		Number num = getNumber(key);
		return num == null? null: num.doubleValue();
	}
	
	private String casekey(Object key){
		if(lowerCase){
			return String.valueOf(key).toLowerCase();
		}else{
			return String.valueOf(key);
		}
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getT(Object key){
		return (T)get(key);
	}
	
	
	
	
	
	
	
	
	/**
	 *
	 * @param tinfo
	 * @return 不为null的字段(不包含主键字段)
	 */
	public List<String> notNullFields(){
		asertnotnull(this.tinfo, "tinfo为null");
		List<String> r = new ArrayList<String>();
		for(String key : tinfo.getFields()){
			if(get(key) != null){
				r.add(key);
			}
		}
		return r;
	}
	
	
	public Tinfo getTinfo(){
		return this.tinfo;
	}
	public XModel setTinfo(Tinfo tinfo){
		this.tinfo = tinfo;
		return this;
	}
	public XModel setTinfo(Class<? extends Tinfo> tinfoclass){
		setTinfo(XManage.getTinfo(tinfoclass));
		return this;
	}
	
}
